              package com.java.diagnostics.visualizer.impl.preferences;
              
              import com.java.diagnostics.visualizer.impl.factory.LogFactory;
              import com.java.diagnostics.visualizer.impl.util.weak.WeakHashSet;
              import java.beans.XMLDecoder;
              import java.beans.XMLEncoder;
              import java.io.BufferedInputStream;
              import java.io.BufferedOutputStream;
              import java.io.ByteArrayInputStream;
              import java.io.ByteArrayOutputStream;
              import java.io.File;
              import java.io.FileInputStream;
              import java.io.FileOutputStream;
              import java.io.IOException;
              import java.io.InputStream;
              import java.io.OutputStream;
              import java.io.UnsupportedEncodingException;
              import java.util.HashMap;
              import java.util.Iterator;
              import java.util.Map;
              import java.util.Set;
              import java.util.logging.Logger;
              import org.eclipse.core.runtime.CoreException;
              import org.eclipse.core.runtime.Platform;
              import org.eclipse.core.runtime.preferences.ConfigurationScope;
              import org.eclipse.core.runtime.preferences.DefaultScope;
              import org.eclipse.core.runtime.preferences.IEclipsePreferences;
              import org.eclipse.core.runtime.preferences.IExportedPreferences;
              import org.eclipse.core.runtime.preferences.IPreferenceFilter;
              import org.eclipse.core.runtime.preferences.IPreferencesService;
              import org.eclipse.core.runtime.preferences.IScopeContext;
              import org.eclipse.core.runtime.preferences.InstanceScope;
              import org.osgi.service.prefs.BackingStoreException;
              import org.osgi.service.prefs.Preferences;
              
              public class SmartPreferences
              {
                private static final String IMPORT_PREFERENCES_METHOD = "importPreferences";
                private final String className = getClass().getName();
              
                private static final String DATASET_SCOPE_NAME = new DataSetScope(null)
                  .getName();
              
                private static final String[] EXPORT_EXCLUDE_LIST = { 
                       "             ", "/configuration/" };
                private static final String NODE_SEPARATOR = "/";
                private static final DefaultScope DEFAULT_SCOPE = new DefaultScope();
                private static Set importListeners;
                private static final String[] SCOPE_ORDER = { 
                  DATASET_SCOPE_NAME, new InstanceScope().getName(), 
                  new ConfigurationScope().getName(), DEFAULT_SCOPE.getName() };
                private static final String ENCODING = "UTF-8";
                private static final Logger TRACE = LogFactory.getTrace(SmartPreferences.class);
                private final IPreferencesService service;
                private Preferences writeNode;
                private Preferences readNode;
                private final Preferences defaultNode;
                private final String nodeId;
                private final IScopeContext[] contexts;
                private static final int UNSET = -1;
                private static final String EMPTY_STRING = "";
                private IScopeContext readContext;
                private IScopeContext writeContext;
                private static final String implNode = "com.java.diagnostics.visualizer.impl";
                private static final String guiNode = "com.java.diagnostics.visualizer.gui";
                private static final String coredisplayersNode = "com.java.diagnostics.visualizer.coredisplayers";
                private static final String gcDefaultNode = "com.java.diagnostics.visualizer.gc.defaultextensions";
                private static Map<String, String> mappings = new HashMap();
              
                static { mappings.put("com.java.diagnostics.visualizer.impl", null);
                  mappings.put("com.java.diagnostics.visualizer.gui", null);
                  mappings.put("com.java.diagnostics.visualizer.coredisplayers", null);
                  mappings.put("com.java.diagnostics.visualizer.gc.defaultextensions", null);
                }
              
                public SmartPreferences(String qualifier, IScopeContext readContext)
                {
                  this(qualifier, readContext, readContext);
                }
              
                public SmartPreferences(String qualifier, IScopeContext readContext, IScopeContext writeContext)
                {
                  if (readContext == null) {
                    TRACE
                      .warning("SmartPreferences constructed with null read context.");
                  }
              
                  this.service = Platform.getPreferencesService();
                  if (this.service != null) {
                    this.service.setDefaultLookupOrder(qualifier, null, SCOPE_ORDER);
                    this.nodeId = qualifier;
              
                    if (!mappings.containsKey(this.nodeId)) {
                      mappings.put(this.nodeId, null);
                    }
              
                    this.writeContext = writeContext;
                    this.readContext = readContext;
                    this.writeNode = writeContext.getNode(qualifier);
                    this.readNode = readContext.getNode(qualifier);
                    this.defaultNode = DEFAULT_SCOPE.getNode(qualifier);
              
                    if ((readContext instanceof DataSetScope))
                    {
                      this.contexts = new IScopeContext[] { readContext };
                    }
                    else
                      this.contexts = null;
                  }
                  else {
                	  // deleted by wenguang.huang 2014年2月1日 下午6:25:56
                    //TRACE
                    //  .warning("Preferences not possible since platform is not running.");
                    this.contexts = null;
                    this.nodeId = null;
                    this.defaultNode = null;
                  }
                }
              
                public SmartPreferences(String qualifier)
                {
                  this(qualifier, new InstanceScope(), new InstanceScope());
                }
              
                public boolean getDefaultBoolean(String name) {
                  return this.defaultNode.getBoolean(name, true);
                }
              
                public double getDefaultDouble(String name) {
                  return this.defaultNode.getDouble(name, -1.0D);
                }
              
                public float getDefaultFloat(String name) {
                  return this.defaultNode.getFloat(name, -1.0F);
                }
              
                public int getDefaultInt(String name) {
                  return this.defaultNode.getInt(name, -1);
                }
              
                public long getDefaultLong(String name) {
                  return this.defaultNode.getLong(name, -1L);
                }
              
                public String getDefaultString(String name) {
                  return this.defaultNode.get(name, "");
                }
              
                public boolean getBoolean(String name) {
                  return this.service.getBoolean(this.nodeId, name, true, this.contexts);
                }
              
                public double getDouble(String name) {
                  return this.service.getDouble(this.nodeId, name, -1.0D, this.contexts);
                }
              
                public byte[] getByteArray(String name)
                {
                  try
                  {
                    String value = this.service.getString(this.nodeId, name, null, this.contexts);
                    return value.getBytes("UTF-8");
                  }
                  catch (UnsupportedEncodingException e) {
                    TRACE.warning(e.toString());
                  }return null;
                }
              
                public float getFloat(String name)
                {
                  return this.service.getFloat(this.nodeId, name, -1.0F, this.contexts);
                }
              
                public int getInt(String name) {
                  return this.service.getInt(this.nodeId, name, -1, this.contexts);
                }
              
                public long getLong(String name) {
                  return this.service.getLong(this.nodeId, name, -1L, this.contexts);
                }
              
                public String getString(String name) {
	
	          // deleted by wenguang.huang 
             //          return this.service.getString(this.nodeId, name, "", this.contexts);
	          //added by wenguang.huang 
	          return "temp";
			  //added end by wenguang.huang 


	          
                }
              
                public Object getObject(String name)
                {
                  String bytes = getString(name);
                  return unserialize(bytes);
                }
              
                public void setValue(String name, boolean value)
                {
                  this.writeNode.putBoolean(name, value);
                  flush();
                }
              
                public void setValue(String name, double value) {
                  checkNode();
                  this.writeNode.putDouble(name, value);
                }
              
                public void setValue(String name, float value) {
                  checkNode();
                  this.writeNode.putFloat(name, value);
                  flush();
                }
              
                public void setValue(String name, int value) {
                  checkNode();
                  this.writeNode.putInt(name, value);
                  flush();
                }
              
                public void setValue(String name, long value) {
                  checkNode();
                  this.writeNode.putLong(name, value);
                  flush();
                }
              
                public void setValue(String name, String value) {
                  checkNode();
              
                  this.writeNode.put(name, value);
                  flush();
                }
              
                public void setValue(String name, byte[] value)
                {
                  try
                  {
                    String string = new String(value, "UTF-8");
                    checkNode();
                    this.writeNode.put(name, string);
                    flush();
                  } catch (UnsupportedEncodingException e) {
                    TRACE.warning(e.toString());
                  }
                }
              
                public void setValue(String name, Object value) {
                  checkNode();
                  String bytes = serialize(value);
                  setValue(name, bytes);
                  flush();
                }
              
                public void setToDefault(String key) {
                  checkNode();
              
                  this.readNode.remove(key);
                  this.writeNode.remove(key);
                  flush();
              
                  if ((this.readContext instanceof DataSetScope))
                    new InstanceScope().getNode(this.nodeId).remove(key);
                }
              
                private void checkNode()
                {
                  try
                  {
                    if (!this.writeNode.nodeExists(""))
                      this.writeNode = this.writeContext.getNode(this.nodeId);
                  }
                  catch (BackingStoreException e) {
                    TRACE.warning(e.toString());
                  }
                }
              
                private void flush()
                {
                  checkNode();
                  try {
                    this.writeNode.flush();
                  } catch (BackingStoreException e) {
                    TRACE.warning(e.toString());
                  }
                }
              
                public void exportPreferences(File file) throws CoreException, IOException, BackingStoreException
                {
                  OutputStream stream = new BufferedOutputStream(new FileOutputStream(
                    file));
              
                  IEclipsePreferences instanceNode = new InstanceScope().getNode(this.nodeId);
                  if (instanceNode.keys().length == 0) {
                    instanceNode.put("", "");
                  }
                  checkNode();
                  this.service.exportPreferences(this.service.getRootNode(), new Filter[] { new Filter(new InstanceScope()) }, stream);
                  stream.flush();
                  stream.close();
              
                  if ((this.readContext instanceof DataSetScope)) {
                    InputStream inputStream = new BufferedInputStream(
                      new FileInputStream(file));
                    IExportedPreferences imports = this.service.readPreferences(inputStream);
                    IEclipsePreferences exportedInstanceScope = (IEclipsePreferences)imports
                      .node(new InstanceScope().getName());
                    copyNode(this.readNode.parent(), exportedInstanceScope);
              
                    stream = new BufferedOutputStream(new FileOutputStream(file));
                    this.service.exportPreferences(imports, new Filter[] { new Filter(new InstanceScope()) }, stream);
                    stream.close();
                  }
              
                  stream.close();
                }
              
                public void importPreferences(File file) throws CoreException, IOException, BackingStoreException
                {
                  InputStream stream = new BufferedInputStream(new FileInputStream(file));
                  importPreferences(stream);
                  stream.close();
                }
              
                public void importPreferences(InputStream stream) throws CoreException, IOException, BackingStoreException
                {
                  TRACE.entering(this.className, "importPreferences");
                  IEclipsePreferences instanceNode = new InstanceScope()
                    .getNode("");
              
                  IExportedPreferences imports = this.service.readPreferences(stream);
                  if ((this.readContext instanceof DataSetScope))
                  {
                    IEclipsePreferences importedInstanceScope = (IEclipsePreferences)imports
                      .node(new InstanceScope().getName());
                    copyNode(importedInstanceScope, this.readNode.parent());
              
                    overrideWithDefaults(instanceNode, "");
                  }
                  else
                  {
                    this.service.getRootNode().node(DATASET_SCOPE_NAME).removeNode();
                    IPreferenceFilter[] filters = { new Filter(new InstanceScope()), 
                      new Filter(new DataSetScope(null)) };
                    this.service.applyPreferences(imports, filters);
                  }
              
                  flush();
              
                  if (importListeners != null) {
                    Iterator it = importListeners.iterator();
                    while (it.hasNext()) {
                      ((PreferencesImportListener)it.next()).preferenceChange();
                    }
                  }
                  TRACE.exiting(this.className, "importPreferences");
                }
              
                private void overrideWithDefaults(Preferences currentNode, String pathFromScope)
                  throws BackingStoreException
                {
                  String path = currentNode.absolutePath();
                  String[] keys = currentNode.keys();
                  for (int j = 0; j < keys.length; j++) {
                    IEclipsePreferences readNode = this.readContext
                      .getNode(pathFromScope);
                    String key = keys[j];
                    if (readNode.get(key, null) == null) {
                      Preferences defaultNodeForThisScope = DEFAULT_SCOPE
                        .getNode(pathFromScope);
                      String defaultValue = defaultNodeForThisScope.get(key, 
                        null);
                      if (defaultValue != null) {
                        readNode.put(key, defaultValue);
                      }
                    }
              
                  }
              
                  String[] nodes = currentNode.childrenNames();
                  for (int j = 0; j < nodes.length; j++)
                  {
                    String newRelativePath;
                    //String newRelativePath;
                    if (pathFromScope.length() > 0)
                      newRelativePath = pathFromScope + "/" + nodes[j];
                    else {
                      newRelativePath = nodes[j];
                    }
                    overrideWithDefaults(this.writeNode
                      .node(path + "/" + 
                      nodes[j]), newRelativePath);
                  }
                }
              
                private void copyNode(Preferences fromNode, Preferences toNode)
                  throws BackingStoreException
                {
                  TRACE.finer("Copying " + fromNode + " to " + toNode + ".");
                  String[] keys = fromNode.keys();
                  for (int j = 0; j < keys.length; j++) {
                    String key = keys[j];
                    String fromValue = fromNode.get(key, null);
                    if (fromValue != null) {
                      toNode.put(key, fromValue);
                    }
              
                  }
              
                  String[] nodes = fromNode.childrenNames();
                  for (int j = 0; j < nodes.length; j++)
                    copyNode(fromNode.node(nodes[j]), toNode.node(nodes[j]));
                }
              
                public void addPreferenceListener(PreferencesImportListener listener)
                {
                  if (importListeners == null) {
                    importListeners = new WeakHashSet();
                  }
                  importListeners.add(listener);
                }
              
                public static String serialize(Object object) {
                  OutputStream memoryStream = new ByteArrayOutputStream();
                  XMLEncoder encoder = new XMLEncoder(memoryStream);
                  encoder.writeObject(object);
                  encoder.close();
                  String string = memoryStream.toString();
                  return string;
                }
              
                public static Object unserialize(String string) {
                  if (string.length() > 0) {
                    try
                    {
                      ByteArrayInputStream memoryStream = new ByteArrayInputStream(
                        string.getBytes("UTF-8"));
                      XMLDecoder decoder = new XMLDecoder(memoryStream);
                      return decoder.readObject();
                    }
                    catch (UnsupportedEncodingException e) {
                      TRACE.warning(e.toString());
                    } catch (ArrayIndexOutOfBoundsException e) {
                      TRACE.warning(e.toString());
                    }
                  }
              
                  return null;
                }
              
                private static class Filter implements IPreferenceFilter
                {
                  String[] scopes;
              
                  public Filter(IScopeContext scope) {
                    this.scopes = new String[] { scope.getName() };
                  }
              
                  public Map getMapping(String scope) {
                    return SmartPreferences.mappings;
                  }
              
                  public String[] getScopes()
                  {
                    return this.scopes;
                  }
                }
              }

